# -*- coding: utf-8 -*-

from openerp.osv import fields, osv

class product_product(osv.osv):
    _inherit = "product.product"
    _order = 'write_date desc'
    _categ_names_pipe = [u'所有产品 / 可销售 / 管',u'All products / Saleable / 管']
    _categ_names_board = [u'所有产品 / 可销售 / 板',u'All products / Saleable / 板']
    
    def is_categ_type(self, cr, uid, ids, field_name, arg, categ_names, context=None):
        res = {}
        for product in self.browse(cr, uid, ids, context=context):
            val = False
            complete_name = product.categ_id.complete_name
            if complete_name in categ_names:
                #此类的根类
                val = True;
            else:
                #此类的子类
                for categ_name in categ_names:
                    if complete_name.startswith(categ_name):
                        val = True
                        break
            res[product.id] = val
        return res    
    #是否为管类
    def is_pipe(self, cr, uid, ids, field_name, arg, context=None):
        return self.is_categ_type(cr, uid, ids, field_name, arg, self._categ_names_pipe, context)
    #是否为板类
    def is_board(self, cr, uid, ids, field_name, arg, context=None):
        return self.is_categ_type(cr, uid, ids, field_name, arg, self._categ_names_board, context)
    
    def onchange_categ(self,cr,uid,ids,categ_id,context=False):
        res = {'value':{'is_pipe':False,'is_board':False}}
        if not categ_id: return res
        categ = self.pool.get('product.category').browse(cr, uid, categ_id, context=context)
        if categ and categ.complete_name:
            complete_name = categ.complete_name
            #判断管类
            if complete_name in self._categ_names_pipe:
                res['value'].update({'is_pipe':True})
            else:
                for categ_name in self._categ_names_pipe:
                    if complete_name.startswith(categ_name):
                        res['value'].update({'is_pipe':True})
                        break
            #判断板类
            if categ.complete_name in self._categ_names_board:
                res['value'].update({'is_board':True})
            else:
                for categ_name in self._categ_names_board:
                    if complete_name.startswith(categ_name):
                        res['value'].update({'is_board':True})
                        break
        return res
        
    _columns = {
        'sp_tax_rate': fields.selection([('0','No purchase Tax'),
                                      ('6','6% purchase tax'),
                                      ('8','8% purchase tax'),
                                      ('17','17% purchase tax')],
                                      'Purchase Price Tax Rate', type='integer',
                                      help="the tax rate in the purchase price"),
         'pur_inv_gap': fields.float(string='Purchase Invoice Gap', 
                                     help="Purchase price gap when need the invoice in purchase"),
         'product_hscode_id': fields.many2one('product.hscode','HS Code'),
         'ret_tax_rate': fields.related('product_hscode_id', 'ret_tax_rate', type="integer", string="Export Return Tax Rate(%)", readonly=True),
         'exp_name_cn': fields.char('Export CN Name',size=64),
         'exp_name_en': fields.char('Export EN Name',size=64),
         
        'pipe_diameter_i_mm': fields.float('管內径-cm',digits=(16,2)),
        'pipe_diameter_i_in': fields.float('管內径-inch',digits=(16,2)),
        'pipe_diameter_i_ft': fields.float('管內径-foot',digits=(16,2)),
        'pipe_diameter_i_m': fields.float('管內径-m',digits=(16,2)),
        'pipe_diameter_i_main': fields.boolean('管內径-是否位主值'),
        'pipe_diameter_e_mm': fields.float('管外径-cm',digits=(16,2)),
        'pipe_diameter_e_in': fields.float('管外径-inch',digits=(16,2)),
        'pipe_diameter_e_ft': fields.float('管外径-foot',digits=(16,2)),
        'pipe_diameter_e_m': fields.float('管外径-m',digits=(16,2)),
        'pipe_diameter_e_main': fields.boolean('管外径-是否位主值'),
        'pipe_thick_mm': fields.float('壁厚-cm',digits=(16,2)),
        'pipe_thick_in': fields.float('壁厚-inch',digits=(16,2)),
        'pipe_thick_ft': fields.float('壁厚-foot',digits=(16,2)),
        'pipe_thick_m': fields.float('壁厚-m',digits=(16,2)),
        'pipe_thick_main': fields.boolean('壁厚-是否位主值'),
        'pipe_length_mm': fields.float('长度-cm',digits=(16,2)),
        'pipe_length_in': fields.float('长度-inch',digits=(16,2)),
        'pipe_length_ft': fields.float('长度-foot',digits=(16,2)),
        'pipe_length_m': fields.float('长度-m',digits=(16,2)),
        'pipe_gap_mm': fields.float('公差-cm',digits=(16,2)),
        'pipe_gap_in': fields.float('公差-inch',digits=(16,2)),
        'pipe_gap_ft': fields.float('公差-foot',digits=(16,2)),
        'pipe_gap_m': fields.float('公差-m',digits=(16,2)),

        'board_thick_mm': fields.float('板厚-cm',digits=(16,2)),
        'board_thick_in': fields.float('板厚-inch',digits=(16,2)),
        'board_thick_ft': fields.float('板厚-foot',digits=(16,2)),
        'board_thick_m': fields.float('板厚-m',digits=(16,2)),
        'board_length_mm': fields.float('板长-cm',digits=(16,2)),
        'board_length_in': fields.float('板长-inch',digits=(16,2)),
        'board_length_ft': fields.float('板长-foot',digits=(16,2)),
        'board_length_m': fields.float('板长-m',digits=(16,2)),
        'board_width_mm': fields.float('板宽-cm',digits=(16,2)),
        'board_width_in': fields.float('板宽-inch',digits=(16,2)),
        'board_width_ft': fields.float('板宽-foot',digits=(16,2)),
        'board_width_m': fields.float('板宽-m',digits=(16,2)),
        'board_gap_mm': fields.float('板公差-cm',digits=(16,2)),
        'board_gap_in': fields.float('板公差-inch',digits=(16,2)),
        'board_gap_ft': fields.float('板公差-foot',digits=(16,2)),
        'board_gap_m': fields.float('板公差-m',digits=(16,2)),
        
         'is_pipe': fields.function(is_pipe,  
                 string='Is Pipe', type='boolean',
                 store=False
                ),
         'is_board': fields.function(is_board,  
                 string='Is Board', type='boolean',
                 store=False
                ),
                                        
        'create_date': fields.datetime('创建日期'), 
        'write_date': fields.datetime('最后修改日期'), 
    }

    _defaults = {
        'sp_tax_rate': '0',
    }
    def _check_main_size(self, cr, uid, ids, context=None):
        res = True;
        for product in self.read(cr, uid, ids, ['is_pipe','pipe_diameter_i_main','pipe_diameter_e_main','pipe_thick_main'], context=context):
            if product['is_pipe']:
                print 'checking pipe'
                if product['pipe_diameter_i_main'] and product['pipe_diameter_e_main'] and product['pipe_thick_main']:
                    res = False
        return res     
        
    _constraints = [(_check_main_size, '內径,外径和壁厚只能有两个为主值!', ['管道相关'])]
    
    def on_change_hscode(self,cr, uid, ids, product_hscode_id):
        value = {'ret_tax_rate':self.pool.get('product.hscode').browse(cr,uid,product_hscode_id).ret_tax_rate}
        return {'value':value}
    def _compute_size(self,from_size,to_size,size):
        #处理类似与'pipe_diameter_i_'的单位名称
        from_size = (from_size.rindex('_') and from_size[from_size.rindex('_')+1:]) or from_size
        to_size = (to_size.rindex('_') and to_size[to_size.rindex('_')+1:]) or from_size
        compute_rule = {'m-->ft':3.280839895,'m-->in':39.37007874,'m-->mm':1000,'ft-->in':12,'ft-->mm':304.8,'in-->mm':25.4}
        rate = compute_rule.get(from_size+'-->'+to_size) \
                or (compute_rule.get(to_size+'-->'+from_size) and 1.0/compute_rule.get(to_size+'-->'+from_size)) \
                or 0
        return size * rate;
    #do one size field group calculation
    #param sizes:4 size dictory:'mm':value,'inch':value,'foot':value,'m':value
    #param main_size: main size name, may be:mm.inch,foot,m
    #return calculated size, same struuctrue with param sizes
    def _calc_size_group_cols(self,sizes,main_size=None):
        if not main_size:
            #get the first not zero value as the main index
            for size,value in sizes.iteritems():
                if value > 0:
                    main_size = size
                    break;
        if not main_size:
            return sizes
        #main size value, used to do the computation later
        main_size_val = sizes.get(main_size)
        #loop to compute the size        
        for size,value in sizes.iteritems():
            if main_size != size:
                #do the computaton from main size to other sizes, and update the value
                sizes.update({size:self._compute_size(main_size,size,main_size_val)})
        return sizes
    #do the size fields calculation
    #param fld_flags dict,is_pipe/is+board
    #vals the fields dict valus will be put to database
    #is_update if create the false, else then true
    #return calculated vals
    def _calc_size_cols(self,fld_flags,vals,is_update): 
        field_size_suffixs = ('mm','in','ft','m')
        field_size_prefixs = {}
        if(fld_flags.get('value').get('is_pipe')):
            field_size_prefixs = ('pipe_diameter_i_','pipe_diameter_e_','pipe_thick_','pipe_length_','pipe_gap_')
        if(fld_flags.get('value').get('is_board')):
            field_size_prefixs = ('board_thick_','board_length_','board_width_','board_gap_')
        
        #fill in the field data by loop
        for prefix in field_size_prefixs:
            sizes = {}
            field_name = None
            main_size = None
            for suffix in field_size_suffixs:
                field_name = prefix+suffix
                if(is_update and not main_size and vals.get(field_name) and vals.get(field_name) > 0):
                    main_size = field_name
                sizes.update({field_name:(vals.get(field_name) or 0.0)})
            #update找不到主单位,则不进行计算
            if is_update and not main_size:
                continue;
            #do one group fields calculation
            vals.update(self._calc_size_group_cols(sizes,main_size))
        return vals  
    
    def _compute_pipe_size(self,cr,uid,id,fld_flags,vals,is_update): 
        #只有管类进行此计算
        if(not fld_flags.get('value').get('is_pipe')):
            return vals;

        #如果'內径,外径,壁厚'数据没有任何变化,不进行计算,直接返回(这是write()中_calc_size_cols()计算的结果,有其中一个尺寸的值,证明那个字段改变了)
        if not vals.get('pipe_diameter_i_mm') and not vals.get('pipe_diameter_e_mm') and not vals.get('pipe_thick_mm'):
            return vals;
                
        #获得主值情况
        if id: prod_info = self.pool.get('product.product').read(cr,uid,id,['pipe_diameter_i_main','pipe_diameter_e_main','pipe_thick_main'])
        pipe_diameter_i_main = False
        if vals.has_key('pipe_diameter_i_main'): 
            pipe_diameter_i_main = vals.get('pipe_diameter_i_main')
        else: 
            pipe_diameter_i_main = prod_info['pipe_diameter_i_main']
        pipe_diameter_e_main = False
        if vals.has_key('pipe_diameter_e_main'): 
            pipe_diameter_e_main = vals.get('pipe_diameter_e_main')
        else: 
            pipe_diameter_e_main = prod_info['pipe_diameter_e_main']
        pipe_thick_main = False
        if vals.has_key('pipe_thick_main'): 
            pipe_thick_main = vals.get('pipe_thick_main')
        else: 
            pipe_thick_main = prod_info['pipe_thick_main']

        #只有两个主值的情况下向下走,否则直接返回        
        if not (pipe_diameter_i_main and pipe_diameter_e_main and not pipe_thick_main) \
            and not (not pipe_diameter_i_main and pipe_diameter_e_main and pipe_thick_main) \
            and not (pipe_diameter_i_main and not pipe_diameter_e_main and pipe_thick_main):
            return vals

        #获得计算的基础数据:內径,外径,壁厚
        data_val = {}
        data_obj = None
        #获得內径数据
        data_obj = vals
        if not vals.get('pipe_diameter_i_mm'):
            #从数据库得到內径
            data_obj = self.pool.get('product.product').read(cr,uid,id,['pipe_diameter_i_mm','pipe_diameter_i_in','pipe_diameter_i_ft','pipe_diameter_i_m'])
        data_val.update({'pipe_diameter_i_mm':data_obj.get('pipe_diameter_i_mm'),
                         'pipe_diameter_i_in':data_obj.get('pipe_diameter_i_in'),
                         'pipe_diameter_i_ft':data_obj.get('pipe_diameter_i_ft'),
                         'pipe_diameter_i_m':data_obj.get('pipe_diameter_i_m'),})
        #获得外径数据
        data_obj = vals
        if not vals.get('pipe_diameter_e_mm'):
            #从数据库得到外径
            data_obj = self.pool.get('product.product').read(cr,uid,id,['pipe_diameter_e_mm','pipe_diameter_e_in','pipe_diameter_e_ft','pipe_diameter_e_m'])
        data_val.update({'pipe_diameter_e_mm':data_obj.get('pipe_diameter_e_mm'),
                         'pipe_diameter_e_in':data_obj.get('pipe_diameter_e_in'),
                         'pipe_diameter_e_ft':data_obj.get('pipe_diameter_e_ft'),
                         'pipe_diameter_e_m':data_obj.get('pipe_diameter_e_m'),})
        #获得壁厚数据
        data_obj = vals
        if not vals.get('pipe_diameter_e_mm'):
            #从数据库得到壁厚
            data_obj = self.pool.get('product.product').read(cr,uid,id,['pipe_thick_mm','pipe_thick_in','pipe_thick_ft','pipe_thick_m'])
        data_val.update({'pipe_thick_mm':data_obj.get('pipe_thick_mm'),
                         'pipe_thick_in':data_obj.get('pipe_thick_in'),
                         'pipe_thick_ft':data_obj.get('pipe_thick_ft'),
                         'pipe_thick_m':data_obj.get('pipe_thick_m'),})            
        
        #主值为:內径,外径
        if pipe_diameter_i_main and pipe_diameter_e_main: 
            vals.update({'pipe_thick_mm':data_val.get('pipe_diameter_e_mm')-data_val.get('pipe_diameter_i_mm'),\
                     'pipe_thick_in':data_val.get('pipe_diameter_e_in')-data_val.get('pipe_diameter_i_in'),\
                     'pipe_thick_ft':data_val.get('pipe_diameter_e_ft')-data_val.get('pipe_diameter_i_ft'),\
                     'pipe_thick_m':data_val.get('pipe_diameter_e_m')-data_val.get('pipe_diameter_i_m')})
        #主值为:內径,壁厚
        if pipe_diameter_i_main and pipe_thick_main: 
            vals.update({'pipe_diameter_e_mm':data_val.get('pipe_diameter_i_mm')+data_val.get('pipe_thick_mm'),\
                     'pipe_diameter_e_in':data_val.get('pipe_diameter_i_in')+data_val.get('pipe_thick_in'),\
                     'pipe_diameter_e_ft':data_val.get('pipe_diameter_i_ft')+data_val.get('pipe_thick_ft'),\
                     'pipe_diameter_e_m':data_val.get('pipe_diameter_i_m')+data_val.get('pipe_thick_m')})
        #主值为:外径,壁厚
        if pipe_diameter_e_main and pipe_thick_main: 
            vals.update({'pipe_diameter_i_mm':data_val.get('pipe_diameter_e_mm')-data_val.get('pipe_thick_mm'),\
                     'pipe_diameter_i_in':data_val.get('pipe_diameter_e_in')-data_val.get('pipe_thick_in'),\
                     'pipe_diameter_i_ft':data_val.get('pipe_diameter_e_ft')-data_val.get('pipe_thick_ft'),\
                     'pipe_diameter_i_m':data_val.get('pipe_diameter_e_m')-data_val.get('pipe_thick_m')})   
        return vals     
    def create(self, cr, uid, vals, context=None):
        #when do saving of creation, do the size calculation of pipe and board
        res = self.onchange_categ(cr,uid,[],vals.get('categ_id'),context=False)
        vals = self._calc_size_cols(res,vals,False)
        #do the calculation among 內径,外径,壁厚
        vals = self._compute_pipe_size(cr,uid,None,res,vals,True)
        return super(product_product, self).create(cr, uid, vals, context=context)  
    def write(self, cr, uid, ids, vals, context=None):
        #get the product category id
        categ_id = None
        if vals.get('categ_id'):
            categ_id = vals.get('categ_id')
        else:
            data = self.pool.get('product.product').read(cr,uid,ids[0],['categ_id'])
            if data: categ_id = data.get('categ_id')[0]
#            categ_id = self.pool.get('product.product').read(cr,uid,ids[0],['categ_id']).get('categ_id').id            
        res = self.onchange_categ(cr,uid,[],categ_id,context=False)
        #when do saving of update, do the size calculation of pipe and board
        vals = self._calc_size_cols(res,vals,True)
        #do the calculation among 內径,外径,壁厚
        vals = self._compute_pipe_size(cr,uid,ids[0],res,vals,True)
        return super(product_product,self).write(cr, uid, ids, vals, context)         
